package service

import (
	"errors"
	"strconv"

	"gitee.com/cyanbleeze/go-image-management/global"
	"gitee.com/cyanbleeze/go-image-management/internal/model"
	"gitee.com/cyanbleeze/go-image-management/pkg/app"
)

type CreateFavoritePictureRequest struct {
	FavoriteID uint `json:"favorite_id,omitempty" binding:"required,min=1"`
	PictureID  uint `json:"picture_id,omitempty" binding:"required,min=1"`
}

type FavoritePictureRequest struct {
	ID uint `json:"id,omitempty" binding:"required,min=1"`
}

type FavoritePictureListRequest struct {
	FavoriteID uint `json:"favorite_id,omitempty" form:"favorite_id,omitempty" binding:"required,min=1"`
}

type UpdateFavoritePictureRequest struct {
	ID         uint `json:"id,omitempty" binding:"required,min=1"`
	FavoriteID uint `json:"favorite_id,omitempty" binding:"required,min=1"`
}

type DeleteFavoritePictureRequest struct {
	ID uint `json:"id" binding:"required,min=1"`
}
type CountFavoritePictureByPIDRequest struct {
	PictureID uint `json:"picture_id,omitempty" binding:"required,min=1"`
}

func (svc *Service) CreateFavoritePicture(params *CreateFavoritePictureRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	_, err := svc.dao.GetFavorite(params.FavoriteID, userID.(uint))
	if err != nil {
		return err
	}
	_, err = svc.dao.GetPublicPicture(params.PictureID)
	if err != nil {
		return err
	}
	err = svc.dao.CreateFavoritePicture(
		params.FavoriteID,
		params.PictureID,
	)
	if err != nil {
		return err
	}
	key := "favorite_picture_count_" + strconv.Itoa(int(params.FavoriteID))
	global.RedisEngine.Incr(svc.ctx, key)
	return nil
}

func (svc *Service) UpdateFavoritePicture(params *UpdateFavoritePictureRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	fp, err := svc.dao.GetFavoritePicture(params.ID)
	if err != nil {
		return err
	}
	_, err = svc.dao.GetFavorite(fp.FavoriteID, userID.(uint))
	if err != nil {
		return err
	}
	_, err = svc.dao.GetFavorite(params.FavoriteID, userID.(uint))
	if err != nil {
		return err
	}
	return svc.dao.UpdateFavoritePicture(
		params.ID,
		params.FavoriteID,
	)
}

func (svc *Service) DeleteFavoritePicture(params *DeleteFavoritePictureRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	fp, err := svc.dao.GetFavoritePicture(params.ID)
	if err != nil {
		return errors.New("收藏图片信息不存在")
	}
	_, err = svc.dao.GetFavorite(fp.FavoriteID, userID.(uint))
	if err != nil {
		return errors.New("收藏图片信息不存在")
	}
	err = svc.dao.DeleteFavoritePicture(
		params.ID,
	)
	if err != nil {
		return err
	}
	key := "favorite_picture_count_" + strconv.Itoa(int(fp.FavoriteID))
	global.RedisEngine.Decr(svc.ctx, key)
	return nil
}

func (svc *Service) GetFavoritePicture(params *FavoritePictureRequest) (*model.FavoritePicture, error) {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return nil, errors.New("登录用户信息不存在")
	}
	fp, err := svc.dao.GetFavoritePicture(params.ID)
	if err != nil {
		return nil, errors.New("收藏图片信息不存在")
	}
	_, err = svc.dao.GetFavorite(fp.FavoriteID, userID.(uint))
	if err != nil {
		return nil, errors.New("收藏图片信息不存在")
	}
	return fp, err
}

func (svc *Service) CountFavoritePictureByPID(params *CountFavoritePictureByPIDRequest) (int, error) {
	var count int
	key := "favorite_picture_count_" + strconv.Itoa(int(params.PictureID))
	val, err := global.RedisEngine.Get(svc.ctx, key).Result()
	if err != nil {
		count, err = svc.dao.CountFavoritePictureListByPID(
			params.PictureID,
		)
		if err != nil {
			return 0, err
		}
		global.RedisEngine.Set(svc.ctx, key, count, 0).Result()
		return count, nil
	}
	return strconv.Atoi(val)

}

func (svc *Service) GetFavoritePictureList(params *FavoritePictureListRequest, pager *app.Pager) ([]*model.Picture, int, error) {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return nil, 0, errors.New("登录用户信息不存在")
	}
	_, err := svc.dao.GetFavorite(params.FavoriteID, userID.(uint))
	if err != nil {
		return nil, 0, err
	}
	fpList, err := svc.dao.GetFavoriteListPictureByFID(
		params.FavoriteID,
		pager.Page,
		pager.PageSize,
	)
	if err != nil {
		return nil, 0, err
	}
	count, err := svc.dao.CountFavoritePictureListByFID(
		params.FavoriteID,
	)
	if err != nil {
		return nil, 0, err
	}
	var ids [][]interface{}
	for _, fp := range fpList {
		ids = append(ids, []interface{}{fp.PictureID})
	}
	pList, err := svc.dao.GetPictureListInID(
		ids,
		pager.Page,
		pager.PageSize,
	)
	if err != nil {
		return nil, 0, err
	}
	return pList, count, nil
}
